/*
 * 描述： <描述>
 * 修改人： rain
 * 修改时间： 2016年9月30日
 * 项目： rainhy-auth
 */
package com.rainhy.auth.authItemManager.springdata.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;

import com.rainhy.auth.authItemManager.springdata.dao.AuthItemRefEntityDao;
import com.rainhy.auth.authItemManager.springdata.entity.AuthItemRefEntity;
import com.rainhy.auth.context.AuthItemRef;

/**
 * SpringDataAuthManager Service
 * 
 * @author rain
 * @version [版本号, 2016年9月30日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Service("com.rainhy.auth.authItemManager.springdata.service")
public class AuthItemRefEntityService {
    
    @Resource(name = "com.rainhy.auth.authItemManager.springdata.dao")
    private AuthItemRefEntityDao dao;
    
    /** 删除所有权限引用 */
    @Transactional
    public void deleteAll() {
        dao.deleteAllInBatch();
    }
    
    /** 根据权限引用查询来查询完整的权限引用实体 */
    public AuthItemRefEntity findByAuthItemRefEntity(AuthItemRefEntity entity) {
        return dao.findOne(Example.of(entity));
    }
    
    /** 根据权限引用 id 查询权限引用 */
    public AuthItemRefEntity findById(String id) {
        return dao.findById(id);
    }
    
    /**
     * 根据"权限引用类型映射权限引用id"查询权限引用
     *
     * @param refType2RefIdMapping
     * 
     * @return Collection<AuthItemRef> 权限引用集合
     * @throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     * @version [版本号, 2016年10月3日]
     * @author rain
     */
    public Collection<AuthItemRef> queryAuthItemRef(final MultiValueMap<String, String> refType2RefIdMapping) {
        List<AuthItemRef> list = new ArrayList<>();
        if (MapUtils.isEmpty(refType2RefIdMapping)) {
            return list;
        }
        
        List<AuthItemRefEntity> authItemRefEntityList = dao.findAll(new Specification<AuthItemRefEntity>() {
            @Override
            public Predicate toPredicate(Root<AuthItemRefEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> andList = new ArrayList<Predicate>();
                for (Map.Entry<String, List<String>> refType2RefIds : refType2RefIdMapping.entrySet()) {
                    String refType = refType2RefIds.getKey();
                    List<String> refIdList = refType2RefIds.getValue();
                    
                    Predicate equal = cb.equal(root.get("authRefType").as(String.class), refType);
                    Predicate in = root.get("authRefId").as(String.class).in(refIdList);
                    andList.add(cb.and(equal, in));
                }
                return cb.or(andList.toArray(new Predicate[0]));
            }
        });
        
        if (CollectionUtils.isNotEmpty(authItemRefEntityList)) {
            for (AuthItemRefEntity authItemRefEntity : authItemRefEntityList) {
                list.add(authItemRefEntity);
            }
        }
        return list;
    }
    
    /** 保存权限引用实体 */
    @Transactional
    public void save(AuthItemRefEntity air) {
        dao.save(air);
    }
    
    /** 返回权限引用数量 */
    public long count() {
        return dao.count();
    }
    
}
